/************************************************************
Copyright (C) Xiong,Hui at www.51embed.com
FileName: init.c
Author: Xiong,Hui huixiong73@gmail.com
Date:08/3/13
Description: initilize the SFRs and variales
Version: 1.0
Function List: 
    1. timer0isr();
History: 
    1. Huixiong 08/3/13 build this moudle
	2. Huixiong 08/3/17 add the led process in timer0's ISR 
***********************************************************/
#include "at89x52.H"
#include <absacc.h>
#include "isr.h"
/*************************************************************
*  Function:timer0isr()
*  Description:ISR of timer0's every 2.5ms interrupt
*  Calls: none
*  Called by: none
*  Input:
*  Output:
*  Return:
*  Others:
    1.timer0 use the interrupt vector 1
	2.this routine use MCU's working register group 2
*  History:
	1. Huixiong 08/3/13 created
	2. Huixiong 08/3/17 add the led display process 
	3. Huixiong 08/3/24	add the matrix-dot LED dispaly process
	4. Huixiong 08/4/22	add the key processing
*************************************************************/
void timer0isr(void)  interrupt 1 using 2
{
	unsigned char data keyin;
	TH0 = 0xF6; 						//2.5ms for AT89S52, system clock is 11.092MHz
	TL0 = 0x00;
	if(++timer >= 4){					 //10ms
		timer = 0;						//reset the value to zero
		timer10msflag = TRUE;
		 /*check the key*/

		/*led display process*/                                
		if(led_flag){					 //switch flag of led display
		    XBYTE[CS4] = 0xFF;           //turn off the led temporarily	bofore display new data
			switch(dispbit++){
			    case 0:	
					XBYTE[CS3] = led_format(led[0]);
					XBYTE[CS4] = LEDCOM1;
					break;
			    case 1:
				    XBYTE[CS3] = led_format(led[1]);;
					XBYTE[CS4] = LEDCOM2;
				    break;
				case 2:
					XBYTE[CS3] = led_format(led[2]);;
					XBYTE[CS4] = LEDCOM3;
					break;
			    case 3:
				    XBYTE[CS3] = led_format(led[3]);;
					XBYTE[CS4] = LEDCOM4;
				    break;
				default:
					dispbit=0;		
		    }
		}else{
			 XBYTE[CS4] = 0xFF;
		}
   	}
	/*matrix-dot LED display*/
	XBYTE[CS1]=ledbit;			 //ouput the row driven signal(first row if ledbit = 1)

 	XBYTE[CS7]=~leddata[ledbit+16];
	XBYTE[CS8]=~leddata[ledbit]; 

	XBYTE[CS9]=~leddata[ledbit+16];
	XBYTE[CS10]=~leddata[ledbit];
	XBYTE[CS11]=~leddata[ledbit+16];
	XBYTE[CS12]=~leddata[ledbit];
	XBYTE[CS13]=~leddata[ledbit+16];
	XBYTE[CS14]=~leddata[ledbit];
	XBYTE[CS15]=~leddata[ledbit+16];
	XBYTE[CS16]=~leddata[ledbit];
	XBYTE[CS17]=~leddata[ledbit+16];
	XBYTE[CS18]=~leddata[ledbit];

	if(++ledbit >= 16){
	    ledbit=0;
	}

    /*check whether there is a key being pushed*/
	switch(keysta){
	    case KEYON:
		    XBYTE[CS6] = 0xF8;
	        keyin = XBYTE[CS19];
	        if((keyin & 0x0f) == 0x0f){
	            if(++keyontimer >= 20){
				    keysta = KEYOFF;    
				}
	        }else{
			    keyofftimer = 0x0;
			}
		    break;
		case KEYOFF: 
             XBYTE[CS6] = 0xFE;
             keyin = XBYTE[CS19] & 0x0f;
			 if(keyin != 0x0f){
			     if(keyin == keylast){
			         if(++keyofftimer >= 20){
				 	     keysta = KEYON;
					     keyflag = TRUE;
						 keyrow = 0;
					     keyvalue = keyin;
						 led[0] = 1;				//only for test
						 led[1] = ~keyvalue & 0x0f;
						 break;
				     }
			     }else{
			         keyofftimer = 0x0;
					 keylast = keyin;
			     }  
			 }else{
			 	 XBYTE[CS6] = 0xFD;
                 keyin = XBYTE[CS19] & 0x0f;
				 if(keyin != 0x0f){
				     if(keyin == keylast){
				         if(++keyofftimer >= 20){
					 	     keysta = KEYON;
						     keyflag = TRUE;
							 keyrow = 1;
						     keyvalue = keyin;
							 led[0] = 2;
							 led[1] = ~keyvalue & 0x0f;
							 break;
					     }
				     }else{
				         keyofftimer = 0x0;
						 keylast = keyin;
				     }  
			     }else{
				     XBYTE[CS6] = 0xFB;
	                 keyin = XBYTE[CS19] & 0x0f;
					 if(keyin != 0x0f){
					     if(keyin == keylast){
					         if(++keyofftimer >= 20){
						 	     keysta = KEYON;
							     keyflag = TRUE;
								 keyrow = 2;
							     keyvalue = keyin;
								 led[0] = 3;
								 led[1] = ~keyvalue & 0x0f;
								 break;
						     }
					     }else{
					         keyofftimer = 0x0;
							 keylast = keyin;
					     }  	 
				     } 
		        }
			}
		    break;
		default:
		    break;
	}
}

/*************************************************************
*  Function: led_format(leddata)
*  Description:	change the data into LED displaying format
*  Calls:  none
*  Called by: timer0isr()
*  Input:  led data
*  Output: led displaying format of the input data
*  Return: led displaying format
*  Others:
*  History:
	1.Huixiong 08/3/17 created
*************************************************************/
unsigned char led_format(unsigned char data leddata) using 2
{
	unsigned char data m;
	switch(leddata)
	{
		case 0:
			m =  LED0;
		   	break;
		case 1:
			m = LED1;
		   	break;
		case 2:
			m = LED2;
		   	break;
		case 3:
			m = LED3;
		   	break;
		case 4:
			m = LED4;
		   	break;
		case 5:
			m = LED5;
		   	break;
		case 6:
			m = LED6;
		   	break;
		case 7:
			m = LED7;
		   	break;
		case 8:
			m = LED8;
		   	break;
		case 9:
			m = LED9;
		   	break;
		default:
			m = LEDERR;
		   	break;
	}
	return m;
}
/*************************************************************
*  Function:uartisr(void)
*  Description:isr of MCU's uart
*  Calls:
*  Called by:
*  Input:
*  Output:
*  Return:
*  Others:
   1.MCU's uart is 9600bps,1,8,0 which had been initialized in init.c 
*  History:
   1.Huixiong 08/4/19 created
*************************************************************/
void uartisr(void) interrupt  4	 
{
	unsigned char data mdata;
	if(RI == 1){					      //here means that serial port received a byte
    	RI = 0;                       //clear the status flag
		mdata = SBUF;
		SBUF = mdata;
		echoflag = 1;
		uartrecebuf[uartreceptr++] = mdata;
		if(mdata == '\r'){         //if received the end flag
			uartreceflag = TRUE;	//set the flag, then process the data frame reveived in the main loop program
		}else if(mdata == '\b'){	 //process the "backspace"
			uartreceptr--;
			uartrecebuf[uartreceptr--] = 0x00;	
		}
	}

    if(TI == 1){								//ISR for sending interruption
    	TI=0;				//clear the flag
		if(uartsendflag == TRUE){			    //sending flag
			if((uartsendbuf[uartsendtempptr-2]=='\r' && uartsendbuf[uartsendtempptr-1] == '\n') || (uartsendptr==uartsendtempptr)){	//compare the sending pointer and the temp pointer to judge whether the data have been sent over
				uartsendtempptr = 0;				//
                uartsendptr = 0;
                uartsendflag = FALSE;
			}else{
				SBUF = uartsendbuf[uartsendtempptr++];	    	//send the data left
			}
		 }else if(echoflag){
		 	echoflag = 0;
		 }
    }
}